<?php
/**
 *  💡 免责声明：本软件不得用于商业用途，仅做学习交流
 *  ⚠️ 权利声明：本软件由版权人提供产品技术支持
 *  📅 项目编号：NX2025-0135
 */
namespace App\Service\User;

use App\Jobs\RefundJob;
use App\Models\OrderBatch;
use App\Models\Refund;
use App\Service\BaseService;
use App\Service\Setting\BeanSettingService;
use Illuminate\Support\Facades\DB;
use InvalidArgumentException;

class RefundService extends BaseService
{
    public function initiateRefund(
        OrderBatch $order
    ): Refund {
        return DB::transaction(function () use ($order) {
            // 创建退款记录
            $setting = BeanSettingService::make()->getSetting();
            $todaySPrice = bcdiv(1, $setting['PRICE'] ?? 1, 2);

//            $paymentBean = bcdiv($order->amount,$setting['PRICE'],2); //KC通证价格换算
//
//            $calculateBeanRefund = $this->calculateBeanRefund($order->amount);

            $nowString = now()->toDateTimeString();
            $amount = $order->payment_balance;
            if ($amount != 0) {
                $amount = bcmul($order->failure_count, $order->balance_unit_price, 2);
            } else {
                $amount = 0;
            }
            $burn = bcmul($order->failure_count, bcsub($order->bean_unit_price, $todaySPrice, 2), 2);
            $refund = Refund::query()->create([
                'batches_id' => $order->id,
                'user_id' => $order->user_id,
                'amount' => $amount,
                'number' => $order->failure_count,
                'gold_amount' => bcmul($order->failure_count, $order->bean_unit_price, 2),
                'burn' => $burn,
                'status' => 'draft',
                'price' => $order->balance_unit_price,
                'requested_at' => $nowString,
                'processed_at' => $nowString,
                'completed_at' => $nowString,
            ]);
            // 提交审核
            $refund->submitForApproval();
            // 默认审核通过
            $refund->markAsApproved();

            // 触发异步任务
            RefundJob::dispatch($refund)
                ->onQueue('group_refund');
            return $refund;
        });
    }

    /**
     * 退钱.
     */
    public function refundAmount(Refund $refund)
    {
        WalletAccountService::make()->consumption(
            $refund->user_id,
            $refund->amount,
            '拼团失败系统自动退款'
        );
    }

    /**
     * 退豆.
     */
    public function refundBean(Refund $refund)
    {
        BeanAccountService::make()->consumption(
            $refund->user_id,
            $refund->gold_amount,
            "拼团失败系统自动退还KC通证,燃烧KC通证{$refund->burn}",
            4
        );
    }

    /**
     * 订单恢复.
     */
    public function restoreInventory(Refund $refund)
    {
    }

    /**
     * 计算KC通证退款和燃烧数量.
     * @param float $originalAmount 原始KC通证数量（必须 > 0）
     * @throws InvalidArgumentException
     * @return array ['refund' => 退回KC通证, 'burn' => 燃烧KC通证]
     */
    public function calculateBeanRefund(float $originalAmount): array
    {
        // 验证输入有效性
        if ($originalAmount <= 0 || ! is_numeric($originalAmount)) {
            throw new InvalidArgumentException('金额必须为大于0的数字');
        }

        // 定义比例
        $rate = $this->getCombustionRate();

        // 计算理论值（保留6位小数精度）
        $refund = round($originalAmount * $rate['REFUND_RATE'], 6);
        $burn = round($originalAmount * $rate['BURN_RATE'], 6);

        // 四舍五入到2位小数
        $refundRounded = round($refund, 2);
        $burnRounded = round($burn, 2);

        // 校准金额误差（解决浮点计算问题）
        $totalRounded = $refundRounded + $burnRounded;
        $difference = round($originalAmount - $totalRounded, 2);

        // 误差补偿逻辑
        if ($difference !== 0.0) {
            $absDiff = abs($difference);
            $adjustValue = round($absDiff, 2);

            if ($difference > 0) {
                // 补偿给退款
                $refundRounded += $adjustValue;
            } else {
                // 从退款扣除
                $refundRounded -= $adjustValue;
            }

            // 二次校验防止溢出
            $refundRounded = max(0, min($originalAmount, $refundRounded));
            $burnRounded = round($originalAmount - $refundRounded, 2);
        }

        return [
            'refund' => $refundRounded,
            'burn' => $burnRounded,
        ];
    }

    /**
     * 获取KC通证燃烧率.
     * @return array|float
     */
    protected function getCombustionRate()
    {
        $setting = BeanSettingService::make()->getSetting();
        $total = $setting['PAYMENT'] * 10;
        $burn_rate = $setting['BURN_RATE'];    //燃烧
        $refund_rate = bcsub($total, $burn_rate, 2);  // 保留
        return [
            'REFUND_RATE' => bcdiv($refund_rate, $total, 2),
            'BURN_RATE' => bcdiv($burn_rate, $total, 2),
        ];
    }
}
